package com.hzlx.web;


import com.hzlx.dto.MenuDto;
import com.hzlx.dto.ResultDto;
import com.hzlx.service.PermissionService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.util.List;
@Slf4j
@RestController
public class PermissionController {
    @Resource
    PermissionService permissionService;
    @GetMapping("/api/menus")
    public Mono<ResultDto<List<MenuDto>>> menus(){
    return    ReactiveSecurityContextHolder.getContext().
            flatMap(ctx->{
                Authentication auth=ctx.getAuthentication();
                if (auth == null){
                    log.warn("认证对象为空,拒绝访问");
                    return Mono.error(new RuntimeException("非法访问:认证信息缺失"));
                }
                log.info("欢迎{}登录",auth.getPrincipal());
                String principal=auth.getPrincipal().toString();
                return Mono.fromCallable(()->permissionService.findMenus(principal))
                        .map(menus->ResultDto.<List<MenuDto>>builder()
                                .code("ok")
                                .data(menus)
                                .build())
                        .subscribeOn(Schedulers.boundedElastic());
            })
            //统一处理所有可能发生的运行时异常
            .onErrorResume(RuntimeException.class,e->{
                log.error("获取菜单过程中发生错误:{}",e.getMessage(),e);
                return Mono.just(ResultDto.<List<MenuDto>>builder().
                        code("error")
                        .message(e.getMessage()).build());
            }).
            //如果ReactiveSecurityContextHolder.getContext()结果为空(没有安全上下文)
            switchIfEmpty(Mono.just(ResultDto.<List<MenuDto>>builder().code("error").message("未找到安全上下文").build()));

    }
}
